#!/usr/bin/env ruby
#
#  Created by jack and phon on 2007-02-24.
#  Copyright (c) 2007. All rights reserved.

class TicTacToeBoard
  attr_reader :currentPlayer
  attr_accessor :board
  
  def initialize
    @currentPlayer = 0
    @board = []    
    #there are 9 positions in a tic-tac-toe board, layout of position is demonstrated below:
    # # # # #
    # 0 1 2 #
    # 3 4 5 #
    # 6 7 8 #
    # # # # #
  end
   
  # Determine wheter location is already occupied by previous moves
  def isOccupied(location)
    if(board[location] == 'X' || board[location] == 'O')
      return true
    else
      return false
    end
  end

  # Determine if a move is valid.
  def validMove(location, player)
    moveDone = 0
    raise "The location attempted to insert is out of range." if location<0 || location>8
    raise "Teachery! Travesty! Blaspheme! How can you cheat your brethren?" if player!=currentPlayer
    
    # If location is not occupied, then make a move
    if (!isOccupied(location))
      # set move in board array
      @board[location] = (@currentPlayer == 0 ? 'X' : 'O')
      # change current player
      @currentPlayer = (@currentPlayer + 1) % 2
      # tell player that made move that the move was valid
      return true
    # Invalid move
    else
      return false
    end
  end
  
  # Define the ways to win a game
  def win(xo)
    #check three across
    return true if @board[0]==xo && @board[1]==xo && @board[2]==xo
    return true if @board[3]==xo && @board[4]==xo && @board[5]==xo
    return true if @board[6]==xo && @board[7]==xo && @board[8]==xo

    #check three verticles
    return true if @board[0]==xo && @board[3]==xo && @board[6]==xo
    return true if @board[1]==xo && @board[4]==xo && @board[7]==xo
    return true if @board[2]==xo && @board[5]==xo && @board[8]==xo
    
    #check two diagnals
    return true if @board[0]==xo && @board[4]==xo && @board[8]==xo
    return true if @board[2]==xo && @board[4]==xo && @board[6]==xo
        
    return false
  end
  
  # This method determines wheter the game is over
  def gameOver
    #returns true if either X or O has won
    return true if win('X')||win('O')
    
    # Check to see if all squares are filled
    moveCounter = 0
    0.upto(8){|i| 
      moveCounter += 1 if @board[i]=='X' || @board[i]=='O'
    }
    # Game Over if 9 moves have been played despite wheter there's a winner or not
    moveCounter>=9 ? true : false 
    # Game is still undetermined if no player has won and there are still open squares.
    
  end
  
  # This method determines wheter the game is still playable
  def gameNotOver
    !gameOver
  end
  
end
